const { executeSql } = require("./db"); // 引入基础执行函数

/**
 * 格式化字段（* 不加反引号，其他字段加反引号）
 * @param {string} field - 字段名（如 '*' 或 'name'）
 * @returns {string} 格式化后的字段
 */
function formatField(field) {
    return field === "*" ? "*" : `\`${field}\``;
}
/**
 * 校验表名/字段名是否在白名单内（防 SQL 注入）
 * @param {string} value - 表名或字段名
 * @param {string[]} whiteList - 允许的白名单
 * @returns {string} 安全的表名/字段名（默认取白名单第一个）
 */
function checkSafeValue(value, whiteList) {
    return whiteList.includes(value) ? value : null;
}

/**
 * 转换条件对象为 SQL WHERE 子句和参数
 * @param {Object} where - 条件对象（如 {id: 1, sex: 1}）
 * @returns {Object} { whereSql: 'WHERE id = ? AND sex = ?', params: [1, 1] }
 */
function parseWhere(where = {}) {
    const keys = Object.keys(where);
    if (keys.length === 0) return { whereSql: "", params: [] };

    const whereSql = `WHERE ${keys.map((key) => `\`${key}\` = ?`).join(" AND ")}`;
    const params = keys.map((key) => where[key]);
    return { whereSql, params };
}

/**
 * 1. 查询单条数据
 * @param {string} table - 表名
 * @param {string[]} fields - 查询字段（默认 ['*']）
 * @param {Object} where - 条件（如 {id: 1}）
 * @param {string[]} tableWhiteList - 表名白名单（必传，防注入）
 * @returns {Promise} 结果 { success, data: 单条数据 }
 */
async function queryOne(table, fields = ["*"], where = {}, tableWhiteList) {
    // 校验表名安全性
    const safeTable = checkSafeValue(table, tableWhiteList);
    if (!safeTable) {
        return {
            success: false,
            message: "表名不合法！"
        };
    }
    // 处理查询字段（用反引号包裹）
    const safeFields = fields.map(formatField).join(", ");
    // 处理条件
    const { whereSql, params } = parseWhere(where);
    console.log("safeFields", safeFields);

    const sql = `SELECT ${safeFields} FROM \`${safeTable}\` ${whereSql} LIMIT 1`;
    const result = await executeSql(sql, params);
    // 只返回第一条数据
    if (result.success) {
        result.data = result.data[0] || null;
    }
    return result;
}

/**
 * 2. 查询多条数据（支持排序）
 * @param {string} table - 表名
 * @param {string[]} fields - 查询字段（默认 ['*']）
 * @param {Object} where - 条件（如 {age: 20}）
 * @param {Object} order - 排序（如 {create_time: 'DESC'}）
 * @param {string[]} tableWhiteList - 表名白名单
 * @returns {Promise} 结果 { success, data: 数组 }
 */
async function queryList(table, fields = ["*"], where = {}, order = {}, tableWhiteList, pageInfo) {
    const safeTable = checkSafeValue(table, tableWhiteList);
    if (!safeTable) {
        return {
            success: false,
            message: "表名不合法！"
        };
    }
    const safeFields = fields.map(formatField).join(", ");
    const { whereSql, params } = parseWhere(where);

    // 处理排序
    let orderSql = "";
    const orderKeys = Object.keys(order);
    if (orderKeys.length > 0) {
        const orderItems = orderKeys.map((key) => {
            const direction = order[key].toUpperCase() === "DESC" ? "DESC" : "ASC";
            return `\`${key}\` ${direction}`;
        });
        orderSql = `ORDER BY ${orderItems.join(", ")}`;
    }
    let sql = `SELECT ${safeFields} FROM \`${safeTable}\` ${whereSql} ${orderSql}`;
    if (pageInfo) {
        const { page, pageSize } = pageInfo;
        // 计算偏移量：(页码-1)*每页条数 → 第2页偏移量=10
        const offset = (page - 1) * pageSize;
        sql += ` LIMIT ${pageSize} OFFSET ${offset}`;
    }
    return await executeSql(sql, params);
}

/**
 * 3. 分页查询（带总条数）
 * @param {string} table - 表名
 * @param {Object} options - 配置 { fields, where, order, page, pageSize }
 * @param {string[]} tableWhiteList - 表名白名单
 * @returns {Promise} 结果 { success, data: { list, total, page, pageSize } }
 */
async function queryPage(table, options, tableWhiteList) {
    const { fields = ["*"], where = {}, order = {}, page = 1, pageSize = 10 } = options;

    // 1. 查询当前页数据
    const listResult = await queryList(table, fields, where, order, tableWhiteList, {
        page,
        pageSize
    });
    if (!listResult.success) return listResult;

    // 2. 查询总条数
    const safeTable = checkSafeValue(table, tableWhiteList);
    if (!safeTable) {
        return {
            success: false,
            message: "表名不合法！"
        };
    }
    const { whereSql, params } = parseWhere(where);
    const countSql = `SELECT COUNT(*) AS total FROM \`${safeTable}\` ${whereSql}`;
    const countResult = await executeSql(countSql, params);
    if (!countResult.success) return countResult;

    const total = countResult.data[0].total;
    return {
        success: true,
        data: {
            list: listResult.data,
            total,
            page: Number(page),
            pageSize: Number(pageSize),
            totalPage: Math.ceil(total / pageSize) // 总页数
        }
    };
}

/**
 * 4. 新增单条数据
 * @param {string} table - 表名
 * @param {Object} data - 新增数据（如 {name: '张三', age: 20}）
 * @param {string[]} tableWhiteList - 表名白名单
 * @returns {Promise} 结果 { success, data: { insertId } }
 */
async function insertOne(table, data, tableWhiteList) {
    const safeTable = checkSafeValue(table, tableWhiteList);
    if (!safeTable) {
        return {
            success: false,
            message: "表名不合法！"
        };
    }
    const keys = Object.keys(data);
    if (keys.length === 0) {
        return { success: false, error: "新增数据不能为空" };
    }

    const fields = keys.map((key) => `\`${key}\``).join(", ");
    const placeholders = keys.map(() => "?").join(", ");
    const params = keys.map((key) => data[key]);

    const sql = `INSERT INTO \`${safeTable}\` (${fields}) VALUES (${placeholders})`;
    const result = await executeSql(sql, params);
    // 返回插入的ID
    if (result.success) {
        result.data = { insertId: result.data.insertId };
    }
    return result;
}

/**
 * 5. 批量新增数据
 * @param {string} table - 表名
 * @param {Object[]} list - 数据数组（如 [{name: 'a'}, {name: 'b'}]）
 * @param {string[]} tableWhiteList - 表名白名单
 * @returns {Promise} 结果 { success, data: { affectedRows } }
 */
async function insertBatch(table, list, tableWhiteList) {
    if (list.length === 0) {
        return { success: false, error: "批量新增数据不能为空" };
    }
    const safeTable = checkSafeValue(table, tableWhiteList);
    if (!safeTable) {
        return {
            success: false,
            message: "表名不合法！"
        };
    }
    const keys = Object.keys(list[0]); // 以第一条数据为准

    const fields = keys.map((key) => `\`${key}\``).join(", ");
    const placeholders = list.map(() => `(${keys.map(() => "?").join(", ")})`).join(", ");
    // 扁平化参数（[ {a:1,b:2}, {a:3,b:4} ] → [1,2,3,4]）
    const params = list.flatMap((item) => keys.map((key) => item[key]));

    const sql = `INSERT INTO \`${safeTable}\` (${fields}) VALUES ${placeholders}`;
    const result = await executeSql(sql, params);
    if (result.success) {
        result.data = { affectedRows: result.data.affectedRows };
    }
    return result;
}

/**
 * 6. 更新数据（必须传 where 条件，防止全表更新）
 * @param {string} table - 表名
 * @param {Object} data - 要更新的字段（如 {name: '新名字'}）
 * @param {Object} where - 条件（如 {id: 1}）
 * @param {string[]} tableWhiteList - 表名白名单
 * @returns {Promise} 结果 { success, data: { affectedRows } }
 */
async function update(table, data, where, tableWhiteList) {
    if (Object.keys(where).length === 0) {
        return { success: false, error: "更新必须传入条件（where），禁止全表更新" };
    }
    if (Object.keys(data).length === 0) {
        return { success: false, error: "更新数据不能为空" };
    }

    const safeTable = checkSafeValue(table, tableWhiteList);
    if (!safeTable) {
        return {
            success: false,
            message: "表名不合法！"
        };
    }
    // 处理更新字段（如 `name` = ? , `age` = ?）
    const setSql = Object.keys(data)
        .map((key) => `\`${key}\` = ?`)
        .join(", ");
    // 处理条件
    const { whereSql, params: whereParams } = parseWhere(where);
    // 合并参数（更新值在前，条件值在后）
    const dataParams = Object.values(data);
    const params = [...dataParams, ...whereParams];

    const sql = `UPDATE \`${safeTable}\` SET ${setSql} ${whereSql}`;
    const result = await executeSql(sql, params);
    if (result.success) {
        result.data = { affectedRows: result.data.affectedRows };
    }
    return result;
}

/**
 * 7. 删除数据（必须传 where 条件，防止全表删除）
 * @param {string} table - 表名
 * @param {Object} where - 条件（如 {id: 1}）
 * @param {string[]} tableWhiteList - 表名白名单
 * @returns {Promise} 结果 { success, data: { affectedRows } }
 */
async function del(table, where, tableWhiteList) {
    if (Object.keys(where).length === 0) {
        return { success: false, error: "删除必须传入条件（where），禁止全表删除" };
    }

    const safeTable = checkSafeValue(table, tableWhiteList);
    if (!safeTable) {
        return {
            success: false,
            message: "表名不合法！"
        };
    }
    const { whereSql, params } = parseWhere(where);

    const sql = `DELETE FROM \`${safeTable}\` ${whereSql}`;
    const result = await executeSql(sql, params);
    if (result.success) {
        result.data = { affectedRows: result.data.affectedRows };
    }
    return result;
}

module.exports = {
    queryOne,
    queryList,
    queryPage,
    insertOne,
    insertBatch,
    update,
    del,
    checkSafeValue // 暴露校验函数，方便自定义使用
};
